package com.mall.shopping.services;

import com.mall.shopping.ICartService;
import com.mall.shopping.constants.ShoppingRetCode;
import com.mall.shopping.converter.CartItemConverter;
import com.mall.shopping.dal.entitys.Item;
import com.mall.shopping.dal.persistence.ItemMapper;
import com.mall.shopping.dto.*;
import com.mall.shopping.utils.ExceptionProcessorUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Slf4j
@Component
@Service(interfaceClass = com.mall.shopping.ICartService.class)
public class CartServiceImpl implements ICartService {

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private ItemMapper itemMapper;

    // @Autowired
    // private CartItemConverter converter;

    @Override
    public CartListByIdResponse getCartListById(CartListByIdRequest request) {
        CartListByIdResponse response = new CartListByIdResponse();

        try {
            request.requestCheck();

            String uid = String.valueOf(request.getUserId());

            // 获取该用户(key)，的购物车数据(二维表：商品id(field)--商品的DTO(value))
            RMap<Long, CartProductDto> rMap = redissonClient.getMap(uid);
            List<CartProductDto> cartProductDtos = new ArrayList<>();

            // 获取所有的field（即商品id
            Set<Long> fieldSet = rMap.readAllKeySet();

            // 根据field获取对应的value（即商品id对应的DTO
            for (Object field : fieldSet) {
                Object value = rMap.get(field);
                cartProductDtos.add((CartProductDto) value);
            }
            response.setCartProductDtos(cartProductDtos);
            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        } catch (Exception e) {
            log.error("CartServiceImpl.getCartListById occur Exception: " + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }

        return response;
    }

    @Override
    public AddCartResponse addToCart(AddCartRequest request) {
        AddCartResponse response = new AddCartResponse();
        try {

            request.requestCheck();
            Long uid = request.getUserId();
            Long productId = request.getItemId();
            Item item = itemMapper.selectByPrimaryKey(productId);

            CartProductDto cartProductDto = CartItemConverter.item2Dto(item);
            cartProductDto.setProductNum(request.getNum());

            // 加入购物车后，商品为选中的状态
            cartProductDto.setChecked("true");

            // 存入到redis：uid--key；productId--field；dto--value
            RMap<Long, CartProductDto> rmap = redissonClient.getMap(String.valueOf(uid));
            // TODO 设置过期时间
            // rmap.expire()

            if (rmap.containsKey(productId)) {
                // 情况一：productId存在；更新dto的num后再存储

                Integer addNum = request.getNum();
                CartProductDto updateDto = rmap.get(productId);
                updateDto.setProductNum(addNum + updateDto.getProductNum());
                rmap.put(productId, updateDto);
                // rmap.put(productId, updateDto.toString());
            } else {
                // 情况二：productId不存在，直接存储
                rmap.put(productId, cartProductDto);
            }

            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());


        } catch (Exception e) {
            log.error("CartServiceImpl.getCartListById occur Exception: " + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }

        return response;
    }

    @Override
    public UpdateCartNumResponse updateCartNum(UpdateCartNumRequest request) {
        UpdateCartNumResponse response = new UpdateCartNumResponse();
        try {
            request.requestCheck();
            Long uid = request.getUserId();
            Long productId = request.getItemId();

            // 获取当前用户的购物车信息
            RMap<Long, CartProductDto> rmap = redissonClient.getMap(String.valueOf(uid));
            // 获取购物车中当前商品的信息
            CartProductDto productDto = rmap.get(productId);
            // 更新商品的数量和checked状态
            productDto.setProductNum(request.getNum());
            productDto.setChecked(request.getChecked());
            // 重新存储到数据库中
            rmap.put(productId, productDto);

            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());


        } catch (Exception e) {
            log.error("CartServiceImpl.getCartListById occur Exception: " + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }

        return response;
    }

    @Override
    public CheckAllItemResponse checkAllCartItem(CheckAllItemRequest request) {

        CheckAllItemResponse response = new CheckAllItemResponse();
        try {

        } catch (Exception e) {
            log.error("CartServiceImpl.getCartListById occur Exception: " + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }


        return response;
    }

    @Override
    public DeleteCartItemResponse deleteCartItem(DeleteCartItemRequest request) {
        DeleteCartItemResponse response = new DeleteCartItemResponse();

        try {
            request.requestCheck();
            Long uid = request.getUserId();
            Long productId = request.getItemId();
            RMap<Long, CartProductDto> rMap = redissonClient.getMap(String.valueOf(uid));

            // 删除指定的商品
            rMap.fastRemove(productId);


            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());


        } catch (Exception e) {
            log.error("CartServiceImpl.getCartListById occur Exception: " + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }

        return response;
    }

    @Override
    public DeleteCheckedItemResposne deleteCheckedItem(DeleteCheckedItemRequest request) {

        DeleteCheckedItemResposne response = new DeleteCheckedItemResposne();


        try {
            request.requestCheck();
            Long uid = request.getUserId();
            RMap<Long, CartProductDto> rMap = redissonClient.getMap(String.valueOf(uid));
            // 获取所有的 productId--Dto
            Set<Map.Entry<Long, CartProductDto>> entrySet = rMap.readAllEntrySet();
            // 删除checked为true的商品
            for (Map.Entry<Long, CartProductDto> entryMap : entrySet) {
                if (entryMap.getValue().getChecked().equals("true"))
                    rMap.fastRemove(entryMap.getKey());
            }

            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());

        } catch (Exception e) {
            log.error("CartServiceImpl.getCartListById occur Exception: " + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }

    @Override
    public ClearCartItemResponse clearCartItemByUserID(ClearCartItemRequest request) {

        ClearCartItemResponse response = new ClearCartItemResponse();

        try {
            request.requestCheck();
            Long uid = request.getUserId();
            List<Long> productIds = request.getProductIds();
            RMap<Long, CartProductDto> rMap = redissonClient.getMap(String.valueOf(uid));

            // 删除已生成订单的商品列表的信息
            for (Long productId : productIds) {
                rMap.fastRemove(productId);
            }

            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());

        } catch (Exception e) {
            log.error("CartServiceImpl.getCartListById occur Exception: " + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }

        return response;
    }
}
